{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# A Simple Circuit"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "f7f6e61934090d63"
  },
  {
   "cell_type": "markdown",
   "source": [
    "Almost everything you need can be imported from package `braandket_circuit`."
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "e91bb74b11a729b5"
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "outputs": [],
   "source": [
    "from braandket_circuit import H, M, Sequential, allocate_qubit"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-25T08:23:43.797122200Z",
     "start_time": "2024-01-25T08:23:39.895692700Z"
    }
   },
   "id": "9fdb245d8b2ff123"
  },
  {
   "cell_type": "markdown",
   "source": [
    "A simple circuit can be defined as below. \n",
    "\n",
    "`H` is the Hadamard gate.\n",
    "\n",
    "`M` is the measurement (to be clear, projective measurement on computation basics).\n",
    "\n",
    "`Sequential` means that these operations are applied one-by-one as the order in the list."
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "3a7c7b46b7cc2274"
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [
    {
     "data": {
      "text/plain": "Sequential([\n\tHadamardGate(),\n\tProjectiveMeasurement(),\n])"
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circuit = Sequential([H, M])\n",
    "\n",
    "circuit"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-25T08:23:43.806727300Z",
     "start_time": "2024-01-25T08:23:43.797122200Z"
    }
   },
   "id": "61e310c337e166b7"
  },
  {
   "cell_type": "markdown",
   "source": [
    "Now we can run the circuit by providing a qubit. A qubit can be prepared by `allocate_qubit` function. And then we can just \"call\" the circuit like a function with that qubit as the argument."
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "7de04e482478dd5"
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "outputs": [
    {
     "data": {
      "text/plain": "(None,\n MeasurementResult(target=<BnkParticle name=q>, value=0, prob=array(0.5)))"
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "qubit = allocate_qubit(name='q')\n",
    "results = circuit(qubit)\n",
    "\n",
    "results"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-25T08:23:43.808732300Z",
     "start_time": "2024-01-25T08:23:43.806219100Z"
    }
   },
   "id": "2919279bb7b707d7"
  },
  {
   "cell_type": "markdown",
   "source": [
    "Since the circuit itself is a sequence of operations, each step potentially can return a result, so the return of this call is a list (actually, an immutable tuple). In this case, we only care about the last result, which is the result of the measurement `M`. So we just take the last element."
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "7f654a0f64af1065"
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "outputs": [
    {
     "data": {
      "text/plain": "MeasurementResult(target=<BnkParticle name=q>, value=0, prob=array(0.5))"
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result = results[-1]\n",
    "\n",
    "result"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-25T08:23:43.818017Z",
     "start_time": "2024-01-25T08:23:43.810733900Z"
    }
   },
   "id": "564a3fb05080abf2"
  },
  {
   "cell_type": "markdown",
   "source": [
    "The result of a measurement is an instance of `MeasurementResult`, consisting of the result value and the probability of getting it. In this case, the value is either `0` or `1`, and the probability is `0.5` for each."
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "b0bc5a2ca4c66cc9"
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "result.value=0\n",
      "result.prob=array(0.5)\n"
     ]
    }
   ],
   "source": [
    "print(f\"{result.value=}\")\n",
    "print(f\"{result.prob=}\")"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-25T08:23:43.819021400Z",
     "start_time": "2024-01-25T08:23:43.816506800Z"
    }
   },
   "id": "5d20ba8b400fe1c2"
  },
  {
   "cell_type": "markdown",
   "source": [
    "It is worth noting that, `MeasurementResult` instances are designed to be iterable, so that we can conveniently destruct it into `result` and `prob`."
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "4b217fdcf8232516"
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "value=0\n",
      "prob=array(0.5)\n"
     ]
    }
   ],
   "source": [
    "value, prob = result\n",
    "\n",
    "print(f\"{value=}\")\n",
    "print(f\"{prob=}\")"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-25T08:23:43.882043800Z",
     "start_time": "2024-01-25T08:23:43.820017400Z"
    }
   },
   "id": "56cb92d3373df042"
  },
  {
   "cell_type": "markdown",
   "source": [
    "We can perform this experiment multiple times. We may get different results every time."
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "90525d0ba1c1733e"
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "experiment 0:\n",
      "\tvalue=1\n",
      "\tprob=array(0.5)\n",
      "experiment 1:\n",
      "\tvalue=0\n",
      "\tprob=array(0.5)\n",
      "experiment 2:\n",
      "\tvalue=0\n",
      "\tprob=array(0.5)\n",
      "experiment 3:\n",
      "\tvalue=1\n",
      "\tprob=array(0.5)\n",
      "experiment 4:\n",
      "\tvalue=0\n",
      "\tprob=array(0.5)\n",
      "experiment 5:\n",
      "\tvalue=0\n",
      "\tprob=array(0.5)\n",
      "experiment 6:\n",
      "\tvalue=1\n",
      "\tprob=array(0.5)\n",
      "experiment 7:\n",
      "\tvalue=0\n",
      "\tprob=array(0.5)\n",
      "experiment 8:\n",
      "\tvalue=1\n",
      "\tprob=array(0.5)\n",
      "experiment 9:\n",
      "\tvalue=0\n",
      "\tprob=array(0.5)\n"
     ]
    }
   ],
   "source": [
    "for i in range(10):\n",
    "    qubit = allocate_qubit(name='q')\n",
    "    results = circuit(qubit)\n",
    "    value, prob = results[-1]\n",
    "\n",
    "    print(f\"experiment {i}:\")\n",
    "    print(f\"\\t{value=}\")\n",
    "    print(f\"\\t{prob=}\")"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-25T08:23:43.882043800Z",
     "start_time": "2024-01-25T08:23:43.826005Z"
    }
   },
   "id": "initial_id"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
